home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / vol16n13.zip / OPENTR.ZIP / OT_SRC.ZIP / OTDOC.CPP < prev    next >
C/C++ Source or Header  |  1997-05-26  |  13KB  |  437 lines

  1. // OTDoc.cpp : implementation of the COpenTrapDoc class
  2. //
  3. // OpenTrap Version 1.00 by Gregory A. Wolking
  4. // Copyright ⌐ 1997 Ziff-Davis Publishing
  5. // First published in PC Magazine, US Edition, July 1997.
  6.  
  7. #include "stdafx.h"
  8. #include "OpenTrap.h"
  9. #include "OTDoc.h"
  10. #include "OTView.h"
  11. #include "OTextern.h"
  12.  
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // COpenTrapDoc
  20.  
  21. IMPLEMENT_DYNCREATE(COpenTrapDoc, CDocument)
  22.  
  23. BEGIN_MESSAGE_MAP(COpenTrapDoc, CDocument)
  24.     //{{AFX_MSG_MAP(COpenTrapDoc)
  25.     //}}AFX_MSG_MAP
  26. END_MESSAGE_MAP()
  27.  
  28. /////////////////////////////////////////////////////////////////////////////
  29. // COpenTrapDoc construction/destruction
  30.  
  31. COpenTrapDoc::COpenTrapDoc()
  32. {
  33.     // Allocate record buffer.
  34.     if (g_pBufferStart == NULL)
  35.         g_pBufferStart = new char[g_intLogSizeK * 1024];
  36.     m_bIsExporting = FALSE;
  37.     SetFilterFlag();
  38. }
  39.  
  40. COpenTrapDoc::~COpenTrapDoc()
  41. {
  42.     // Delete record buffer.
  43.     if (g_pBufferStart)
  44.     {
  45.         delete [] g_pBufferStart;
  46.         g_pBufferStart = NULL;
  47.     }
  48. }
  49.  
  50. BOOL COpenTrapDoc::OnNewDocument()
  51. {
  52.     if (!CDocument::OnNewDocument())
  53.         return FALSE;
  54.     if (g_pBufferStart == NULL)    // Make sure buffer exists.
  55.     {
  56.         MessageBox(NULL, "Could not allocate memory", "OpenTrap", MB_ICONINFORMATION);
  57.         return FALSE;
  58.     }
  59.     g_pNextRec = g_pBufferStart;    // Reset pointers and flags to indicate buffer is empty.
  60.     g_intRecCount = 0;
  61.     g_bLogFull = FALSE;
  62.     g_pLastRecord = NULL;
  63.     return TRUE;
  64. }
  65.  
  66. /////////////////////////////////////////////////////////////////////////////
  67. // COpenTrapDoc serialization
  68.  
  69. void COpenTrapDoc::Serialize(CArchive& ar)
  70. {
  71.     CDocument::Serialize(ar);
  72.     if (ar.IsStoring())
  73.     {
  74.         // Write signature
  75.         ar.Write("otlog", 6);
  76.         // Write record count
  77.         ar.Write(&g_intRecCount, sizeof(g_intRecCount));
  78.         // followed by raw data.
  79.         ar.Write(g_pBufferStart, g_pNextRec - g_pBufferStart);
  80.     }
  81.     else
  82.     {
  83.         // Get pointer to file object.
  84.         CFile * cf = ar.GetFile();
  85.         // Get file size.
  86.         DWORD len = cf->GetLength();
  87.         // Default result is bad format.
  88.         UINT result = IDP_BAD_FILE_FORMAT;
  89.         DWORD count = 0, data_size;
  90.         UINT bytes_read;
  91.         char signature[6];
  92.         // File must be at least large enough to
  93.         // hold 6 byte signature, DWORD for the record count,
  94.         // and one record (empty logs cannot be saved).
  95.         if (len > (6 + sizeof(DWORD) + sizeof(struct packed_record) + 1))
  96.         {
  97.             // Verify that file signature (first six bytes) is "otlog" in ASCIIZ format.
  98.             if (ar.Read(signature, 6) == 6)
  99.             {
  100.                 if (lstrcmp(signature, "otlog") == 0)
  101.                 {
  102.                     // Retrieve record count.
  103.                     if (ar.Read(&count, sizeof(count)) == sizeof(count))
  104.                     {
  105.                         // See how much data there is to load.
  106.                         data_size = len - 6 - sizeof(count);
  107.                         // Make sure buffer is large enough.
  108.                         if (Check_Buffer_Size(data_size))
  109.                         {
  110.                             // Read data into buffer
  111.                             bytes_read = ar.Read(g_pBufferStart, data_size);
  112.                             // If successful,
  113.                             if (bytes_read == data_size)
  114.                             {
  115.                                 // Clear error status
  116.                                 result = 0;
  117.                                 // and set new record count.
  118.                                 g_intRecCount = count;
  119.                             }
  120.                         }
  121.                         else
  122.                             result = IDP_BUFFER_ALLOC_FAIL;
  123.                     }
  124.                 }
  125.             }
  126.         }
  127.         // If result code is non-zero,
  128.         if (result)
  129.             // Display corresponding error message.
  130.             AfxMessageBox(result, 0);
  131.         else
  132.             // Otherwise, update record pointers.
  133.             Fix_Pointers(count);
  134.      }
  135. }
  136.  
  137. /////////////////////////////////////////////////////////////////////////////
  138. // COpenTrapDoc diagnostics
  139.  
  140. #ifdef _DEBUG
  141. void COpenTrapDoc::AssertValid() const
  142. {
  143.     CDocument::AssertValid();
  144. }
  145.  
  146. void COpenTrapDoc::Dump(CDumpContext& dc) const
  147. {
  148.     CDocument::Dump(dc);
  149. }
  150. #endif //_DEBUG
  151.  
  152. /////////////////////////////////////////////////////////////////////////////
  153. // COpenTrapDoc commands
  154.  
  155.  
  156. BOOL COpenTrapDoc::OnOpenDocument(LPCTSTR lpszPathName) 
  157. {
  158.     if (!CDocument::OnOpenDocument(lpszPathName))
  159.         return FALSE;
  160.     UpdateAllViews(NULL, 0, 0);
  161.     return TRUE;
  162. }
  163.  
  164. BOOL COpenTrapDoc::OnSaveDocument(LPCTSTR lpszPathName) 
  165. {
  166.     return CDocument::OnSaveDocument(lpszPathName);
  167. }
  168.  
  169. // Makes sure buffer is large enough to hold the data we need to load.
  170. // Reallocates buffer if necessary, returns FALSE if unable to do so.
  171. BOOL COpenTrapDoc::Check_Buffer_Size(DWORD data_size)
  172. {
  173.     DWORD data_size_K;
  174.     char * new_buf;
  175.  
  176.     if (data_size < (g_intLogSizeK * 1024))    // If buffer is large enough,
  177.         return TRUE;                        // Nothing to do, so signal success.
  178.     data_size_K = (data_size / 1024) + 16;    // Calculate size needed; add 16K to allow further logging.
  179.     if (data_size_K < 2048)                    // Upper limit is 2048K
  180.         data_size_K = 2048;
  181.     new_buf = (char *) realloc(g_pBufferStart, data_size_K * 1024);    // Try to reallocate buffer.
  182.     if (new_buf)                                // If successful,
  183.     {
  184.         g_pBufferStart = g_pNextRec = new_buf;        // Reset pointers,
  185.         g_intLogSizeK = data_size_K;                // set new buffer size,
  186.         return TRUE;                                // and signal success.
  187.     }
  188.     else                                        // Otherwise,
  189.         return FALSE;                                // signal failure.
  190. }
  191.  
  192.  
  193. // Rebuilds record pointers after a log is loaded from disk
  194. // or the buffer has been reallocated.
  195. // On exit, g_pLastRecord points to the last record in the
  196. // file and g_pNextRec points to the position for the
  197. // next record to be added.
  198. void COpenTrapDoc::Fix_Pointers(DWORD count)
  199. {
  200.     struct packed_record * pr = NULL, *lr = NULL;
  201.     DWORD i;
  202.  
  203.     BeginWaitCursor();
  204.     g_pNextRec = g_pBufferStart;                // Point to beginning of buffer.
  205.     g_pLastRecord = NULL;                        // First record has no previous record.
  206.     for (i = 1; i <= count; i++)
  207.     {
  208.         pr = (packed_record *) g_pNextRec;        // Update record pointer.
  209.         pr->prev_record = g_pLastRecord;        // Set previous record pointer.
  210.         pr->pr_file1 = NULL;
  211.         if (pr->pr_function == IFSFN_CLOSE)        // Was it a Close event?
  212.         {
  213.             lr = pr;                                    // Start looking with current record.
  214.             while ((lr = lr->prev_record))                // Look back until beginning of file is reached
  215.             {
  216.                 if (pr->pr_handle == lr->pr_handle)        // for an event with the same file handle...
  217.                 {
  218.                     if (lr->pr_function == IFSFN_OPEN)    // that was an Open....
  219.                     {
  220.                         pr->pr_file1 = lr->pr_file1;    // if found, point to its filename string.
  221.                         break;
  222.                     }
  223.                 }
  224.             }
  225.         }
  226.         g_pNextRec += sizeof(packed_record);        // Calculate string position.
  227.         if (pr->pr_file1 == NULL)                    // If string pointer is not already set,
  228.             pr->pr_file1 = g_pNextRec;                // Set it to current buffer position.
  229.         while (*g_pNextRec++);                        // Skip string.
  230.         if (i == count)                                // Set next record pointer.
  231.             pr->next_record = NULL;
  232.         else
  233.             pr->next_record = (packed_record *) g_pNextRec;
  234.         g_pLastRecord = pr;                            // Save pointer for next record.
  235.     }
  236.     EndWaitCursor();
  237. }
  238. // Creates a text file using the contents of the log buffer.
  239. void COpenTrapDoc::Write_Text_Log(CString file_name)
  240. {
  241.     HANDLE file_handle;
  242.     struct packed_record * p = (struct packed_record *) g_pBufferStart;
  243.     char workbuf[1024];
  244.     DWORD havewritten;
  245.     int recs_out = 0, rec_num = 0;
  246.  
  247.     file_handle=CreateFile(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0,0);
  248.     m_bIsExporting = TRUE;
  249.     while(TRUE)
  250.     {
  251.         ++rec_num;
  252.         if ((g_bWriteFiltered ? Filter_Record(p) : TRUE))
  253.         {
  254.             ++recs_out;
  255.             Packed_to_ASCII(rec_num, p, workbuf);
  256.             WriteFile(file_handle, workbuf, strlen(workbuf), &havewritten, NULL);
  257.         }
  258.         if ( (p = p->next_record) == NULL)
  259.             break;
  260.     }
  261.     if (g_bWriteFiltered && (recs_out == 0))
  262.     {
  263.         lstrcpy(workbuf, "No records found matching current filter criteria\r\n");
  264.         WriteFile(file_handle, workbuf, strlen(workbuf), &havewritten, NULL);
  265.     }
  266.     CloseHandle(file_handle);
  267.     m_bIsExporting = FALSE;
  268. }
  269.  
  270. // Takes pointer to packed record in memory buffer
  271. // and formats it as ASCII text into a buffer provided by the caller.
  272. void COpenTrapDoc::Packed_to_ASCII(int rec_num, struct packed_record *p, char *b)
  273. {
  274.     char *t = b, *tl, *fname, *func, *pgm;
  275.     char status[3] = {0,0,0};
  276.     static char dummy_name[] = "a file on drive x:";
  277.  
  278.     if (strlen(p->pr_file1) > 2)
  279.         fname = p->pr_file1;                        // Default to current filename.
  280.     else
  281.     {
  282.         fname = dummy_name;
  283.         dummy_name[16] = *p->pr_file1;
  284.     }
  285.     if (m_bIsExporting && g_bCommaDelimited)
  286.     {
  287.         switch (p->pr_function)
  288.         {
  289.         case IFSFN_OPEN:
  290.             status[0] = 'O';
  291.             break;
  292.         case IFSFN_CLOSE:
  293.             status[0] = 'C';
  294.             break;
  295.         default:
  296.             status[0] = 'U';
  297.         }
  298.         status[1] = p->pr_error ? '*' : ' ';
  299.         func = status;
  300.     }
  301.     else
  302.     {
  303.         if (p->pr_function == IFSFN_OPEN)
  304.             func = (p->pr_error) ? "failed to open" : "opened";
  305.         else
  306.         {
  307.             if (p->pr_function == IFSFN_CLOSE)
  308.                 func = (p->pr_error) ? "failed to close" : "closed";
  309.             else
  310.                 func = (p->pr_error) ? "failed to do who knows what to" : "did who knows what to";
  311.         }
  312.     }
  313.     pgm = (p->pr_program[0] == '\0') ? "<unknown>" : p->pr_program;
  314.     tl = ctime(&(p->pr_time.time));
  315.     if (m_bIsExporting && g_bCommaDelimited)
  316.     {
  317.         if (g_bExportRecNums)
  318.             t += sprintf(t, "%06u,\"%s\",\"%s\",\"%s\",\"%.8s.%hu\"\r\n", rec_num, pgm, func, fname, &tl[11], p->pr_time.millitm);
  319.         else
  320.             t += sprintf(t, "\"%s\",\"%s\",\"%s\",\"%.8s.%hu\"\r\n", pgm, func, fname, &tl[11], p->pr_time.millitm);
  321.     }
  322.     else
  323.     {
  324.         if (m_bIsExporting ? g_bExportRecNums : g_bShowNums)
  325.             t += sprintf(t, "%06u %s %s %s at %.8s.%hu\r\n", rec_num, pgm, func, fname, &tl[11], p->pr_time.millitm);
  326.         else
  327.             t += sprintf(t, "%s %s %s at %.8s.%hu\r\n", pgm, func, fname, &tl[11], p->pr_time.millitm);
  328.     }
  329.     *t = '\0';
  330. }
  331.  
  332. // Sets flag if any of the view filters are in effect.
  333. void COpenTrapDoc::SetFilterFlag(void)
  334. {
  335.     g_bUseFilters = (g_intFilterEvents != 0) ||
  336.                     g_bFilterErrorsOnly ||
  337.                     g_bFilterFileExt ||
  338.                     g_bFilterFileName ||
  339.                     g_bFilterModule;
  340. }
  341.  
  342. // Determines whether or not the specified record matches
  343. // the current filter criteria.
  344. BOOL COpenTrapDoc::Filter_Record(void * p)
  345. {
  346.     const packed_record* const r = (packed_record*) p;
  347.     BOOL result = TRUE;
  348.  
  349.     if (g_bUseFilters)
  350.     {
  351.         switch (g_intFilterEvents)
  352.         {
  353.         case 0:    break;
  354.         case 1:    result = (r->pr_function == IFSFN_OPEN); break;
  355.         case 2:    result = (r->pr_function == IFSFN_CLOSE);
  356.         }
  357.         if (result && g_bFilterErrorsOnly)
  358.             result = (r->pr_error !=0);
  359.         if (result && g_bFilterFileName)
  360.             result = Wildcard_Compare(r->pr_file1, TRUE);
  361.         if (result && g_bFilterFileExt)
  362.             result = Wildcard_Compare(r->pr_file1, FALSE);
  363.         if (result && g_bFilterModule)
  364.         {
  365.             if (g_strFilterModuleName.IsEmpty())
  366.                 result &= (*r->pr_program == '0');
  367.             else
  368.                 result &= (g_strFilterModuleName.CompareNoCase(r->pr_program) == 0);
  369.         }
  370.     }
  371.     return result;
  372. }
  373.  
  374. // Function used to check a filename or extension filter using wildcards.
  375. // Input:
  376. // s1 = Start of buffer containing a fully qualified filename in ASCIIZ format.
  377. // If "which" parameter indicates:
  378. //    TRUE = filename;
  379. //    FALSE = extension.
  380. // Returns TRUE if comparison succeeds.
  381. // Note: This function is case-sensitive, but in this 
  382. //       program, filenames and filters are always uppercase-only.
  383. BOOL COpenTrapDoc::Wildcard_Compare(char *buffer, BOOL which)
  384. {
  385.     const char *s1 = buffer;
  386.     const char *s2;
  387.     BOOL sresult = TRUE;                    // Default comparison result is TRUE.
  388.     s2 = NULL;
  389.     while (*s1)                                // Loop to end of buffer.
  390.     {
  391.         if (*s1 == (which ? '\\' : '.'))    // Is character a backslash/dot?
  392.             s2 = s1;                        // save position if so.
  393.         ++s1;                                // Next character.
  394.     }
  395.     if (s2)                    // Was a backslash/dot found?
  396.     {
  397.         s1 = s2 + 1;        // Start comparison at first char after the backslash/dot.
  398.         s2 = (which    ? g_strFilterFileName : g_strFilterFileExt);
  399.         while (*s1 && *s2)                    // Loop until end of either string in reached.
  400.         {
  401.             if (*s1 != *s2)                    // Chars match?
  402.             {
  403.                 if (*s2 != '?')                // Was filter char not a "?" ?
  404.                 {
  405.                     if (*s2 == '*')            // If not, was it a "*"?
  406.                         break;                // Done if so; comparison succeeds.
  407.                     sresult = FALSE;        // Otherwise, we're still done but comparison fails.
  408.                     break;
  409.                 }
  410.             }
  411.             ++s1;
  412.             ++s2;
  413.         }
  414.         if (sresult)
  415.         {
  416.             if (which)
  417.                 // For filenames, comparison must have stopped while pointing at:
  418.                 // Either a dot or the end of the filename string,
  419.                 // And either an asterisk or the end of the filter string.
  420.                 return (*s2 == '*') || ((*s1 == '.' || *s1 == '\0') && (*s2 == '\0'));
  421.             else
  422.                 // For extensions, comparison must have stopped while pointing
  423.                 // at either the end of the filename string or an asterisk in the filter string.
  424.                 return (*s1 == '\0' || *s2 == '*');
  425.         }
  426.         else
  427.             return FALSE;
  428.     }
  429.     // If we got this far, the trailing dot/backslash was not found.
  430.     else
  431.         // So if we're checking the filename, return false.
  432.         // If we're checking the extension, return TRUE if the filter
  433.         // string is either empty or just the "*" wildcard.
  434.         return which ? FALSE : (g_strFilterFileExt.IsEmpty() || g_strFilterFileExt[0] == '*');
  435. }
  436.  
  437.